package com.example.pos_link_print;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import androidx.annotation.NonNull;

import com.pax.poslinkperipheries.POSLinkPeripheries;
import com.pax.poslinkperipheries.ProcessResult;
import com.pax.poslinkperipheries.printer.POSLinkPrinter;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** PosLinkPrintPlugin */
public class PosLinkPrintPlugin implements FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private POSLinkPrinter.PrintDataFormatter printDataFormatter;
  private Context context;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    printDataFormatter = new POSLinkPrinter.PrintDataFormatter();
    context = flutterPluginBinding.getApplicationContext();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "pos_link_print");
    channel.setMethodCallHandler(this);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    String content = "";
    switch (call.method) {
      case "clear":
        printDataFormatter.clear();
        result.success(true);
        break;
      case "leftAlign":
        printDataFormatter.addLeftAlign();
        result.success(true);
        break;
      case "rightAlign":
        printDataFormatter.addRightAlign();
        result.success(true);
        break;
      case "centerAlign":
        printDataFormatter.addCenterAlign();
        result.success(true);
        break;
      case "content":
        content = call.argument("content");
        printDataFormatter.addContent(content);
        result.success(true);
        break;
      case "smallFont":
        printDataFormatter.addSmallFont();
        result.success(true);
        break;
      case "normalFont":
        printDataFormatter.addNormalFont();
        result.success(true);
        break;
      case "bigFont":
        printDataFormatter.addBigFont();
        result.success(true);
        break;
      case "header":
        printDataFormatter.addHeader();
        result.success(true);
        break;
      case "trailer":
        printDataFormatter.addTrailer();
        result.success(true);
        break;
      case "disclaimer":
        printDataFormatter.addDisclaimer();
        result.success(true);
        break;
      case "date":
        printDataFormatter.addDate();
        result.success(true);
        break;
      case "time":
        printDataFormatter.addTime();
        result.success(true);
        break;
      case "sn":
        printDataFormatter.addSN();
        result.success(true);
        break;
      case "invert":
        printDataFormatter.addInvert();
        result.success(true);
        break;
      case "lineSeparator":
        printDataFormatter.addLineSeparator();
        result.success(true);
        break;
      case "barcode":
        if (call.argument("type") != null && call.argument("blockSize") != null) {
          Integer type = call.argument("type");
          Integer blockSize =call.argument("blockSize");
          content = call.argument("content");
          printDataFormatter.addBarcode(type, blockSize, content);
        }
        result.success(true);
        break;
      case "print":
        print(result);
        break;
      case "printImg":
        byte[] imgBytes = call.argument("imgBytes");
        if (call.argument("location") != null) {
          Bitmap imgBitmap = bytesToBitmap(imgBytes);
          Integer location = call.argument("location");
          printImg(imgBitmap,location,result);
        }
        break;
    }
  }
  public Bitmap bytesToBitmap(byte[] byteArray) {
    return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
  }
  public void printImg(Bitmap imgBitmap,int index,Result result){
    int cutMode = POSLinkPrinter.CutMode.DO_NOT_CUT;
    List<Integer> valueList = Arrays.asList(0, 1, 2);
    POSLinkPeripheries.getInstance(context).getPrinter().print(imgBitmap, cutMode, new POSLinkPrinter.PrintListener() {
      @Override
      public void onSuccess() {
        result.success(true);
      }

      @Override
      public void onError(ProcessResult processResult) {
        result.success(false);
      }
    }, (int) valueList.get(index));
  }

  public void print(Result result){
    int cutMode = POSLinkPrinter.CutMode.DO_NOT_CUT;
    POSLinkPeripheries.getInstance(context).getPrinter().print(printDataFormatter.build(), cutMode,
            new POSLinkPrinter.PrintListener() {
              @Override
              public void onSuccess() {
                printDataFormatter.clear();
                result.success(true);
              }

              @Override
              public void onError(ProcessResult processResult) {
                printDataFormatter.clear();
                result.success(false);
              }
            });
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}
